/*
Copyright 2024 New Vector Ltd.
Copyright 2017 Vector Creations Ltd
Copyright 2014 OpenMarket Ltd

SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
 */

#import "MatrixKit.h"

#import "RoomTitleView.h"

#import "RoomPreviewData.h"

#import "RoomParticipantsViewController.h"

#import "ContactsTableViewController.h"

#import "UIViewController+RiotSearch.h"

@class BadgeLabel;
@class UniversalLinkParameters;
@protocol RoomViewControllerDelegate;
@class RoomDisplayConfiguration;
@class ThreadsCoordinatorBridgePresenter;
@class LiveLocationSharingBannerView;
@class VoiceBroadcastService;
@class ComposerLinkActionBridgePresenter;

NS_ASSUME_NONNULL_BEGIN

/**
 Notification string used to indicate call tile tapped in a room. Notification object will be the `RoomBubbleCellData` object.
 */
extern NSNotificationName const RoomCallTileTappedNotification;

/**
 Notification string used to indicate group call tile tapped in a room. Notification object will be the `RoomBubbleCellData` object.
 */
extern NSNotificationName const RoomGroupCallTileTappedNotification;
/**
 Duration for the composer resize animation.
 */
extern NSTimeInterval const kResizeComposerAnimationDuration;

@interface RoomViewController : MXKRoomViewController


// The delegate for the view controller.
@property (weak, nonatomic, nullable) id<RoomViewControllerDelegate> delegate;

// The preview header
@property (weak, nonatomic, nullable) IBOutlet UIView *previewHeaderContainer;
@property (weak, nonatomic, nullable) IBOutlet NSLayoutConstraint *previewHeaderContainerHeightConstraint;
@property (weak, nonatomic, nullable) IBOutlet NSLayoutConstraint *completionSuggestionContainerHeightConstraint;

// The jump to last unread banner
@property (weak, nonatomic, nullable) IBOutlet UIView *jumpToLastUnreadBannerContainer;
@property (weak, nonatomic, nullable) IBOutlet UIView *jumpToLastUnreadBanner;
@property (weak, nonatomic, nullable) IBOutlet UIImageView *jumpToLastUnreadImageView;
@property (weak, nonatomic, nullable) IBOutlet UIButton *jumpToLastUnreadButton;
@property (weak, nonatomic, nullable) IBOutlet UILabel *jumpToLastUnreadLabel;
@property (weak, nonatomic, nullable) IBOutlet UIButton *resetReadMarkerButton;
@property (weak, nonatomic, nullable) IBOutlet UIView *inputBackgroundView;
@property (weak, nonatomic, nullable) IBOutlet UIButton *scrollToBottomButton;
@property (weak, nonatomic, nullable) IBOutlet BadgeLabel *scrollToBottomBadgeLabel;
@property (nonatomic, strong) IBOutlet UIView *overlayContainerView;

// Remove Jitsi widget container
@property (weak, nonatomic, nullable) IBOutlet UIView *removeJitsiWidgetContainer;

// Error presenter
@property (nonatomic, strong, readonly) MXKErrorAlertPresentation *errorPresenter;

/**
 Preview data for a room invitation received by email, or a link to a room.
 */
@property (nonatomic, readonly, nullable) RoomPreviewData *roomPreviewData;

/**
 Display configuration for the room view controller.
 */
@property (nonatomic, readonly) RoomDisplayConfiguration *displayConfiguration;

/**
 Tell whether a badge must be added next to the chevron (back button) showing number of unread rooms.
 YES by default.
 */
@property (nonatomic) BOOL showMissedDiscussionsBadge;

/**
 ID of the parent space. `nil` for home space.
 */
@property (nonatomic, nullable) NSString *parentSpaceId;

/// Handles all banners that should be displayed at the top of the timeline but that should not scroll with the timeline
@property (weak, nonatomic, nullable) IBOutlet UIStackView *topBannersStackView;

/// Indicate YES to show live location sharing banner
@property (nonatomic, readonly) BOOL shouldShowLiveLocationSharingBannerView;

/// Displayed live location sharing banner if any
@property (nonatomic, weak) LiveLocationSharingBannerView *liveLocationSharingBannerView;

// The customized room data source for Vector
@property (nonatomic, nullable) RoomDataSource *customizedRoomDataSource;

// The voice broadcast service
@property (nonatomic, nullable) VoiceBroadcastService *voiceBroadcastService;

@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray<NSLayoutConstraint*> *toolbarContainerConstraints;

@property (strong, nonatomic, nullable) UIView* maximisedToolbarDimmingView;

@property (nonatomic) CGFloat wysiwygTranslation;

@property (nonatomic, strong, nullable) ComposerLinkActionBridgePresenter *composerLinkActionBridgePresenter;

@property (weak, nonatomic, nullable) UIViewController *waitingOtherParticipantViewController;
@property (nonatomic) BOOL isWaitingForOtherParticipants;

/**
 Retrieve the live data source in cases where the timeline is not live.

 @param onComplete completion block
 */
- (void)setupRoomDataSourceToResolveEvent: (void (^)(MXKRoomDataSource *roomDataSource))onComplete;

/**
 Cancels current event selection inside the timeline.
 */
- (void)cancelEventSelection;

/**
 Display the preview of a room that is unknown for the user.

 This room can come from an email invitation link or a simple link to a room.

 @param roomPreviewData the data for the room preview.
 */
- (void)displayRoomPreview:(RoomPreviewData*)roomPreviewData;

/**
 Display a new discussion with a target user without associated room.
 
 @param directChatTargetUser Direct chat target user.
 @param session The Matrix session.
 */
- (void)displayNewDirectChatWithTargetUser:(nonnull MXUser*)directChatTargetUser session:(nonnull MXSession*)session;

/**
 Pop to home view controller
 */
- (void)popToHomeViewController;

/**
 If `YES`, the room settings screen will be initially displayed. Default `NO`
 */
@property (nonatomic) BOOL showSettingsInitially;

/**
 Action used to handle some buttons.
 */
- (IBAction)onButtonPressed:(id)sender;

- (IBAction)scrollToBottomAction:(id)sender;

/**
 Highlights an event in the timeline. Does not reload room data source if the event is already loaded. Otherwise, loads a new data source around the given event.
 
 @param eventId Identifier of the event to be highlighted.
 @param completion Completion block to be called at the end of process. Optional.
 */
- (void)highlightAndDisplayEvent:(NSString *)eventId completion:(nullable void (^)(void))completion;

/**
 Creates and returns a new `RoomViewController` object.
 
 @param configuration display configuration for the room view controller.
 
 @return An initialized `RoomViewController` object.
 */
+ (instancetype)instantiateWithConfiguration:(RoomDisplayConfiguration *)configuration;

@end

/**
 `RoomViewController` delegate.
 */
@protocol RoomViewControllerDelegate <NSObject>

/**
 Tells the delegate that the user wants to open the room details (members, files, settings).
 
 @param roomViewController the `RoomViewController` instance.
 */
- (void)roomViewControllerShowRoomDetails:(RoomViewController *)roomViewController;

/**
 Tells the delegate that the user wants to display the details of a room member.
 
 @param roomViewController the `RoomViewController` instance.
 @param roomMember the selected member
 */
- (void)roomViewController:(RoomViewController *)roomViewController
         showMemberDetails:(MXRoomMember *)roomMember;

/**
 Tells the delegate that the user wants to display another room.
 
 @param roomViewController the `RoomViewController` instance.
 @param roomID the selected roomId
 @param eventID the selected eventId
 */
- (void)roomViewController:(RoomViewController *)roomViewController
            showRoomWithId:(NSString *)roomID
                   eventId:(nullable NSString *)eventID;

/**
 Tells the delegate that the room has replaced by a room with a specific replacement room ID.
 
 @param roomViewController the `RoomViewController` instance.
 @param roomID the replacement roomId
 */
- (void)roomViewController:(RoomViewController *)roomViewController
didReplaceRoomWithReplacementId:(NSString *)roomID;

/**
 Tells the delegate that the user wants to start a direct chat with a user.
 
 @param roomViewController the `RoomViewController` instance.
 @param userId the selected user id
 @param completion Blocks called when the chat is created.
 */
- (void)roomViewController:(RoomViewController *)roomViewController
       startChatWithUserId:(NSString*)userId
                completion:(void (^)(void))completion;

/**
 Tells the delegate that the user wants to show complete security screen.
 
 @param roomViewController the `RoomViewController` instance.
 @param session The selected Matrix session.
 */
- (void)roomViewController:(RoomViewController *)roomViewController showCompleteSecurityForSession:(MXSession*)session;

/**
 Tells the delegate that the user left the room.
 
 @param roomViewController the `RoomViewController` instance.
 */
- (void)roomViewControllerDidLeaveRoom:(RoomViewController *)roomViewController;

/**
 Tells the delegate that the user wants to cancel the room preview.
 
 @param roomViewController the `RoomViewController` instance.
 */
- (void)roomViewControllerPreviewDidTapCancel:(RoomViewController *)roomViewController;

/**
 Process universal link.
 
 @param roomViewController the `RoomViewController` instance.
 @param parameters the universal link parameters.
 @return YES in case of processing success.
 */
- (BOOL)roomViewController:(RoomViewController *)roomViewController
handleUniversalLinkWithParameters:(UniversalLinkParameters*)parameters;

/**
 Ask the coordinator to invoke the poll creation form coordinator.
 
 @param roomViewController the `RoomViewController` instance.
 */
- (void)roomViewControllerDidRequestPollCreationFormPresentation:(RoomViewController *)roomViewController;

/**
 Ask the coordinator to invoke the location sharing form coordinator.
 
 @param roomViewController the `RoomViewController` instance.
 */
- (void)roomViewControllerDidRequestLocationSharingFormPresentation:(RoomViewController *)roomViewController;

/**
 Ask the coordinator to invoke the location sharing form coordinator.
 
 @param roomViewController the `RoomViewController` instance.
 @param event the event containing location information
 @param bubbleData the bubble data containing sender details
 */
- (void)roomViewController:(RoomViewController *)roomViewController
didRequestLocationPresentationForEvent:(MXEvent *)event
                bubbleData:(id<MXKRoomBubbleCellDataStoring>)bubbleData;

/// Ask the coordinator to present the live location sharing viewer.
- (void)roomViewController:(RoomViewController *)roomViewController
didRequestLiveLocationPresentationForBubbleData:(id<MXKRoomBubbleCellDataStoring>)bubbleData;

- (nullable UIActivityViewController *)roomViewController:(RoomViewController *)roomViewController
              locationShareActivityViewControllerForEvent:(MXEvent *)event;

- (BOOL)roomViewController:(RoomViewController *)roomViewController
canEndPollWithEventIdentifier:(NSString *)eventIdentifier;

- (void)roomViewController:(RoomViewController *)roomViewController
endPollWithEventIdentifier:(NSString *)eventIdentifier;

- (BOOL)roomViewController:(RoomViewController *)roomViewController
canEditPollWithEventIdentifier:(NSString *)eventIdentifier;

- (void)roomViewController:(RoomViewController *)roomViewController
didRequestEditForPollWithStartEvent:(MXEvent *)startEvent;

/**
 Indicate to the delegate that loading should start
 
 Note: Only called if the controller can delegate user indicators rather than managing
 loading indicators internally
 */
- (void)roomViewControllerDidStartLoading:(RoomViewController *)roomViewController;

/**
 Indicate to the delegate that loading should stop
 
 Note: Only called if the controller can delegate user indicators rather than managing
 loading indicators internally
 */
- (void)roomViewControllerDidStopLoading:(RoomViewController *)roomViewController;

/// User tap live location sharing stop action
- (void)roomViewControllerDidStopLiveLocationSharing:(RoomViewController *)roomViewController beaconInfoEventId:(nullable NSString*)beaconInfoEventId;

/// User tap live location sharing banner
- (void)roomViewControllerDidTapLiveLocationSharingBanner:(RoomViewController *)roomViewController;

/// Request a threads coordinator for a given threadId, used to open a thread from within a room.
- (nullable ThreadsCoordinatorBridgePresenter *)threadsCoordinatorForRoomViewController:(RoomViewController *)roomViewController threadId:(nullable NSString *)threadId;

@end

NS_ASSUME_NONNULL_END
